MAI(Micro Algorithm Instruction) ――――――――――――――――――――――――――――――――――――――― アスキー 1983年 1月号掲載 PC−8001 マシン語 0A400H−0B3FFH 実行方法 CLEAR 300,&HA3FF MON L GA400 コールドスタート 0A400H ホット スタート 0A40FH ――――――――――――――――――――――――――――――――――――――― マイコンを使っていらっしゃる方で ゲームが大好きという人は多いと思います。 かく言う私もゲーム人好き人間の一人です。 そしてゲームの中でもゲームセンタータイプのゲーム、 あのなつかしきインベーダーゲームから始まった リアルタイムゲームが相変わらずすごい人気のようです。 ところでこのリアルタイムゲームのプログラミングで 最も問題になるのがスピードです。 しかし市販されているマイコンのほとんどは BASICインタプリタ内蔵です。 このBASICというのは憶えやすく 使いやすい言語なのですが、 速度を重視するプログラムを組むには不向きです。 ここでお目見えするのがインタプリタ言語より 一桁速いコンパイラ言語です。 コンパイラというと、 大西氏の手によるGAMEのコンパイラ、 同じく大西氏のTL/1がASCII誌生で発表されています、 特にGAMEコンパイラは いろいろとアプリケーションが発表されています。 私もGAME−PCとそのコンパイラが 発表されたときはその速度に感激し、 いくつかプログラムを組みましたが、 やがて不満な点がいくつかあらわれてきました。 GAMEの欠点としては、  1.メモリを多く必要とする。    (インタプリタとコンパイラで約13K byte)  2.変数がA〜Zの26個しかない  3.コンパイルされたプログラムはインタプリタがないと使えない などが挙げられます。 またアセンブラを使い始めたため、 ラベルジャンプができな不便に思いました。 そこでこれらの不便な点を解消すべくコンパイラ言語を作ってみました。 これがMAI(Micro Algorithm Instruction)です。   ・―――――――――――――――・  /            特  徽| ・―――――――――――――――――・ 1.テキストエディタ、コンパイラ、サブルーチンパッケージを   すべて含んで4Kbyteで小型である。 2.ベンチマークテストではGAME−PCコンパイラより高速である。 3.文法的にはGAMEに近く、より構造的なプログラムが組みやすい。 4.オブジェクトプログラはサブルーチンパッケージとリンクされ、   この2つがあればプログラムは実行できる。   (TL/1と同じ、サプルーチンパッケージは、ランタイムルーチンと    オプションルーチンを合わせたものて、こう呼んでいる。)   ・―――――――――――――――・  /            入力方法| ・―――――――――――――――――・ MAIは機械語でできていますので、 モニタのSコマンドを使って入力しなければなりません。 まず、CLEAR 300,&HA3FF[RET]と入力した後、 モニタでダンプリストを打ち込みます。 左端の4桁はアドレス、右端の2桁の数字は チェツクサムですので、入力する必要はありません (チェックサムについては1982年11月号  TBNマイコンなんでも相談室参照のこと)。 入力が終ったらまずカセットにセーブして下さい。 MAIは機械語で書かれていますから、 数バイトの入力ミスでも暴走してしまう可能性があるからです。 セーブの方法は、  WA400,B3FF[RET] セーブが終ったら実行です。実行は、  GA400[RET] また、一度実行すれば ファンクションキー1に“MON[RET]GA400[RET]”が定義されますので、 BASICからはf−1でホットスタートが可能です。 なお、MAIの製成するオブジェクトプログラムは 独立して使用することが可能です。 この場合、ライブラリと合わせてオブジェクトを セーブしておかなければなりません。 この方法はモニタより、  WB000,オブジェクトエンド番地[RET] とします。またその実行はMAIがない状態で、  GB022[RET] とします。   ・―――――――――――――――・  /             使い方| ・―――――――――――――――――・ MAIはコンパイラ言語のため、 ソースプログラムを直接実行できません。 そこでコンパイル命令でコンパイルして機械語に変換して実行します。 シースプログラムはテキストエディタからキーインあるいは テープからロードします。 なぜTL/1のようにBASICのエディタを使わなっかたのか、 それはメモリ効率と使いやすさからこのようにしました。 BASICのREMこそ利用すると 一行につき8byteのソース以外のメモリを使います。 しかし専用のエディタでは1byteで済みます。 この差し引き7byteがどうしたと思われるかもしれませんが、 100行のプログラムでは700byte、 200行のプログラムでは1.4Kbyteもの差がでてしまいます。 またMAIのプログラムを見ればわかりますが、 MAIには行番号が存在しません。 GOTO、GOSUBの飛び先はすべてラベルになるわけです。 つまりアセンブラのように必要な行にラベルをつけて飛ばすわけです。 そこでポインタ方式のエディタにしたわけです。 使いやすさという意味はコンパイルするのにも実行するのにも すべてエディタからできる方が便利と考えたからです。 そういう意味ではこのエディタが MAI全体を管理していると考えられます。 テキストエディタは一部のコマンド名を除いて PROTのエディタと全く同じです。 しかしテキストエリアの変更は無意味です。 ソースプロブラムを入力したらコンパイルします。 これはC[RET]、Z[RET]のいずれかで行います。 C[RET]はリスト付のコンパイル命令で ソースプログラムの各行に対してのソースとしての アドレスとオブジェクトとしてのアドレスを出力します。 これは2回出力されますが、コンパイルが2PASS方式のためです。 Z[RET]はリストを出力しない代わりにコンパイル時間が短くなります。 エラーがでるとコンパイルは中止です。 このときエラーのでた行とエラーの種類が出力されるので 修正して再度コンパイルします。 コンパイルが無事終了したらR[RET]を実行します。 f−5キーでもかまいません。 あとはソースなりオブジェクトなりセーブすればよいでしょう。 細かい手順についてはリファレンスカードを参照して下さい。 ・−−−−−−−−−−−−−−−−−−−−−−−−−−−・ |メモリマップ | |8023・------------・ | | | | | | | ソース・エリア | | | | | | | | | | |A400|------------| | | | | | | | MAI | | | | | E000 コンパイル時 実行時 | |B400|------------| ・----------------------------・ | | | | | | | | | | | | | | | | | | | | | |ラベル&変換 | フリーエリア | | | |オブジェクト・エリア| | | テーブル | | | | | | | | | | | | | | | | | | | | | | | | | | | |E000|------------|--・ E800|----------|----------| | | | MAIワーク・エリア | | ワークエリア | ワークエリア | | |EA00|------------|--・ E840|----------|----------| | | | | | | | 変数エリア | | | | PC ワーク・エリア | | | ラベルスタック | | | | | | | | ↑ | | | |FF40|------------| ・----------------------------・ | | |MAI ワーク&スタック| EA0C | |FFFF・------------・ | |                           | |                           | |システムエントリーポインタ              | |・−−−−−−−−−−−−−−−−−−−−−−−−−・| ||プログラム・エリア |A400-B3FF (4Kbyte) || ||コールド・スタート |A400 || ||ホット・スタート |A40F || ||システム・スタック |FFFF || ||−−−−−−+−−−−−−−−−−−−−−−−−−|| ||ソース・エリア |8023〜A3FF (9Kbyte) || || ||テキスト・エンドのチェックは行なわないため、| || || ||エディタの重ならないように | || || ||注意すること。 | || ||オブジェクト・エリア|B400〜DFFF(11Kbyte) || ||ワーク・エリア |E000〜E9FF(2.5Kbyte) || || |ラベル&変数テーブル || || |システム・ワーク・エリア || || |変数エリア || || ||実行時にはE000〜E7FFはフリー・エリアに | || || ||なるので、配列に使うとよい。 | || |・−−−−−−−−−−−−−−−−−−−−−−−−−・| ・−−−−−−−−−−−−−−−−−−−−−−−−−−−・   ・―――――――――――――――・  /         プログラミング| ・―――――――――――――――――・ 先ほど触れましたがMAIはGAMEと文法的に近いのですが 異なる点も多くあります。 これらをまとめてみますと、 1.行番号は存在せずラベルを使用する。   これによりプログラムは組みやすく、見やすくなる。 2.変数は6文字以内でいくらでも作れる。   しかしメモリの関係上220個程度までである。 3.コメントは“%”を用いる。 4.IF〜THEN〜ELSE〜END、REPEAT〜UNTIL、   WHILE〜WENDにより、   構造的なプログラムが書きやすい。   BASIC、GAMEと異なり   IF文でTHEN、ELSEの後には複数行にわたった文が書ける。 5.GOTO、GOSUB文ではパラメータが使え、   メインプログラムとサブルーチン間とで変数の受けわたしができる。   しかしPASCAL等の言語のように   スタックを用いた受け渡たしではないので   再帰的には使うことができない。 6.メモリに対して連続したデータを書き込む命令を持っており、   機械語ともリンクしやすい。   これはBASICではDATA文のデータをREADして   POKEすることに対応している。 7.PCのグラフィック能力を発揮させるための   オプションルーチンを用意している。 以上ですが、GAMEに比べて劣る点もあります。 1.右づめ出力の桁数が固定されている。 2.FOR〜NEXT文がない。 理由は、(1)このままでも十分に使えること。 (2)コンパイラのサイズと相談してのこと。 (3)筆者が怠慢な性格であること。 この3つが絡み合っているためです。 (3)がほとんどを占めているかもしれませんが。 プログラムの形はサンプルプログラムをご覧になればわかると思いますが、 スペースをいくら使ってもよいので 字下げを行ってPASCALライクな形になります。 (PASCALモドキが正解でしょう。) しかしMAIにはローカル変数、パラメータを伴った再帰呼び出しはできません。 これは、いろいろと考えたのですが、Z−80でこれらを行うと速度、 メモリ効率の点で不利になると思えたためです。 またコンパイラ自体も大きくなってしまうため省略しました。 これから文法の説明に入るわけですが。 まずサンプルとして素数を求めるプログラムを載せておきます。 これは80年4月号のGAME−APPLEコンパイラの サンプルプログラムを書き直したものです。 GAMEを使っている人なら一目でGAMEに似ていることがわかるでしょう。 ところが8、9、15行目に見慣れぬものがあります。 8行目の“=”はIF文の終わりを示します。 MAIではIF文の後に文を書くことができるため“;”を用います。 9行目の“[+”は変数のインクリメント命令です。 15行目の“-”はEND文に相当します。 このプログラムをコンパイルすると オブジェクトサイズ135byteが表示されます。 実行時間は19秒でした。 以上のようなサンプルプログラムに目が慣れたところで MAIの文法について説明しましょう。 ・−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−・ |サンプルプログラム1 素数を求めるプログラム          | | 00001: %"■■■■ SOSU ■■■■                | | 00002: "START"/ | | 00003: "2" / | | 00004: A=3 | | 00005: @ | | 00006: B=2 | | 00007: @ | | 00008: ;=A%B=0 #=NEXT ; | | 00009: @=B[+>A-1 | | 00010: ?=A / | | 00011: NEXT | | 00012: A=A+2 | | 00013: @=A>500 | | 00014: "End" | | 00015: - | |                                | | オブジェクト 135byte                 | | 実行時間   19秒                     | |                                | |サンプルプログラム2                      | |オブジェクトプログラムのディスアセンブルリスト | | ORG 0B400H | | B400 CD6CB0 CALL PLN | | B403 53746172 DB 'Star' | | B407 74 DB 't' | | B408 00 DB 0 | | ; | | B409 CDCA5F CALL CRLF | | B40C CD6CB0 CALL PLN | | B40F 32 DB '2' | | B410 00 DB 0 | | ; | | B411 CDCA5F CALL CRLF | | B414 210300 LD HL,3 | | B417 2240E8 LD (VARA),HL | | B41A 210200 LOOP1: LD HL,2 | | B41D 2242E8 LD (VARB),HL | | B420 2A40E8 LOOP2: LD HL,(VARA) | | B423 EB EX DE,HL | | B424 2A42E8 LD HL,(VARB) | | B427 CDEDB1 CALL MOD | | B42A EB EX DE,HL | | B42B D5 PUSH DE | | B42C 210000 LD HL,0 | | B42F D1 POP DE | | B430 CD34B0 CALL EO | | B433 7C LD A,H | | B434 B5 OR L | | B435 CA3BB4 JP Z,IF1 | | B438 C361B4 JP NEXT | | ; | | B43B 2A42E8 IF1: LD HL,(VARB) | | B43E 23 INC HL | | B43F 2242E8 LD (VARB),HL | | B442 EB EX DE,HL | | B443 D5 PUSH DE | | B444 2A40E8 LD HL,(VARA) | | B447 EB EX DE,HL | | B448 210100 LD HL,1 | | B44B EB EX DE,HL | | B44C AF XOR A | | B44D ED52 SBC HL,DE | | B44F D1 POP DE | | B450 CD4DB0 CALL GT | | B453 7C LD A,H | | B454 B5 OR L | | B455 CA20B4 JP Z,LOOP2 | | B458 2A40E8 LD HL,(VARA) | | B45B CD97B0 CALL PDL | | B45E CDCA5F CALL CRLF | | B461 2A40E8 NEXT: LD HL,(VARA) | | B464 EB EX DE,HL | | B465 210200 LD HL,2 | | B468 19 ADD HL,DE | | B469 2240E8 LD (VARA),HL | | B46C 2A40E8 LD HL,(VARA) | | B46F EB EX DE,HL | | B470 D5 PUSH DE | | B471 21F401 LD HL,N500 | | | | | | | | | | B474 D1 POP DE | | B475 CD4DB0 CALL GT | | B478 7C LD A,H | | B479 B5 OR L | | B47A CA1AB4 JP Z,LOOP1 | | B47D CD6CB0 CALL PLN | | B480 456E64 DB 'End' | | B483 00 DB 0 | | ; | | B484 CD83B1 CALL END | ・−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−・   ・―――――――――――――――・  /       ベンチマークテスト| ・―――――――――――――――――・ MAIの特徴についてはすでに述べたとおりですが、 これらの特徴の中でも特筆すぺき点に高速性があります。 もちろん、MAIはコンパイラ言語であるためでもあるわけですが、 WHILE〜DO文等によるループ処理、ラベルによるジャンプ等も 高速処理を実現している要因の大きな1つでもあります。 月刊アスキーロードテストで使われている ベンチマークプログラムの実行時間はトータルで4.32秒と 高速性を誇っています。 MAIは、月刊アスキーの標準言語とも言える “GAME”のインタプリタ、コンパイラを一つにまとめ、 さらに専用エディタを加えた形のコンパイラ言語ですが、 4Kbyteと非常にコンパクトに作られています。 また、一部を除いてGAME言語との記述の統一があり、 GAME言語で書かれたブログラムをMAIに移植することも簡単でしょう。 コンパイラ部分、エディタ部分が一つにまとめられているため、 エディタによるソースプログラムの作成からコンパイル、 実行までが効率良く行えます。 ・−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−・ |             ベンチマークテスト               | |プログラム1 |■■■0.07sec                   | |プログラム2 |■■■■■0.09Sec                 | |プログラム3 |■■■■■■■■■■■■■■■■■1.19sec     | |プログラム4 |■0.49sec                     | |プログラム5 |■■0.50sec                    | |プログラム6 |■■■■0.86sec                  | |プログラム7 |■■■■■■■■■■■■■■■■■■■1.20sec   | |−−−−−−−+−−−−−−−−−−−−−−−−−−−−−        | |  合 計  | 4.32秒                       | ・−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−・      †   †   † 第2回では、MAIの構造と各エントリーポイントについて、 詳細な文法解説、GAMEからの移植について、 アプリケーションプログラム等について予定しています。